package pri.abner.practice.thread.sequentialexecution;

import java.util.concurrent.*;

/**
 *@description CachedThreadPool + FutureTask 保证顺序执行
 *@author abner chow
 *@date 2019-08-30 16:57
 */
public class Execution3 {

    public static void main(String[] args) {

        FutureTask<Integer> f1 = new FutureTask<Integer>(new Work(null, "Thread 1"));
        FutureTask<Integer> f2 = new FutureTask<Integer>(new Work(f1, "Thread 2"));
        FutureTask<Integer> f3 = new FutureTask<Integer>(new Work(f2, "Thread 3"));

        // 有界队列
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(5);

        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 30, TimeUnit.SECONDS, workQueue);
        threadPool.execute(f1);
        threadPool.execute(f2);
        threadPool.execute(f3);
        threadPool.shutdown();
        try {
            if (threadPool.awaitTermination(6, TimeUnit.SECONDS)) {
                threadPool.shutdownNow();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class Work implements Callable<Integer> {

        private FutureTask<Integer> beforeFutureTask;

        private String name;


        Work(FutureTask<Integer> beforeFutureTask, String name) {
            this.beforeFutureTask = beforeFutureTask;
            this.name = name;
        }

        @Override
        public Integer call() throws Exception {
            try {
                if (null != beforeFutureTask) {
                    Integer result = beforeFutureTask.get();
                    System.out.println(this.name + " start...");
                } else {
                    System.out.println(this.name + " start...");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }

}
